<template>
	<div class="build">
		<contentmenu ref="contentmenu" @handleContentmenu="handleContentmenu"></contentmenu>
		<imglist ref="imglist" @change="handleSetimg"></imglist>
		<headers ref="header"></headers>
		<div class="app pages-wrapper" :class="{ 'app--none': !menuFlag }">
			<div class="menu" :class="{ 'menu-hide': menuFlag && !menuShow }" @click.self="handleMouseDown">
				<div class="header">
					<div class="name">图层</div>

					<div class="btns">
						<div
							class="head_btn"
							:class="{
								'head_btn--active': layer.thumbnailVersion
							}"
							@click="handleFlag"
						>
							<el-tooltip effect="dark" content="缩略图版" placement="bottom">
								<i class="el-icon-monitor"></i>
							</el-tooltip>
						</div>
						<div class="head_btn" :class="{ 'head_btn--active': layer.textVersion }" @click="handleFlag">
							<el-tooltip effect="dark" content="文字版" placement="bottom">
								<i class="el-icon-coin"></i>
							</el-tooltip>
						</div>
					</div>
				</div>
				<layer ref="layer" :nav="compsList" :showType="layer"></layer>
			</div>
			<!-- 中间区域 -->
			<div ref="section" class="section">
				<div class="refer-line-img" @click="imgClick" :title="isShowReferLine ? '隐藏参考线' : '显示参考线'">
					<img :src="isShowReferLine ? imgOpenData : imgClose" />
				</div>

				<sketch-rule
					:thick="thick"
					:scale="scale"
					:width="width"
					:height="height"
					:startX="startX"
					:startY="startY"
					:isShowReferLine="isShowReferLine"
					:palette="palette"
					:shadow="shadow"
					:horLineArr="lines.h"
					:verLineArr="lines.v"
				/>
				<div
					ref="screensRef"
					id="screens"
					:class="dragSlide ? 'dragghanle' : ''"
					@mousedown.stop="dragMousedown"
					@mouseup="dragMouseup"
					@mousemove="dragMousemove"
					@wheel="handleWheel"
					@scroll="handleScroll"
				>
					<div ref="containerRef" class="screen-container">
						<div class="canvas" ref="canvas" :style="canvasStyle">
							<container ref="container" :wscale="scale" @changeCanvasScale="changeCanvasScale"></container>
						</div>
					</div>
				</div>
			</div>
			<div class="menu params" :class="{ 'menu-hide': menuFlag && !paramsShow }">
				<p class="pageConfig-title" v-if="activeCompsIndex.length === 0">页面设置</p>
				<div class="title title--left" v-else>
					<div class="compInfo">
						<div class="compInfo-title">
							{{ activeObj.title }}
						</div>
						<span class="compInfo-rename" v-if="!activeObj.isRename" @click="handleReCompName">重命名</span>
						<el-input size="mini" @change="editCompName" :clearable="false" v-if="activeObj.isRename" :disabled="activeObj.isLock" v-model="activeObj.name"></el-input>
					</div>
					<div class="compDesc">
						<div class="com-doc-icon" v-if="activeObj.component">[{{ activeObj.component.name }}]</div>
						<div class="version-index" :title="activeObj.index">{{ activeObj.index }}</div>
					</div>
				</div>
				<el-tabs class="tabs" stretch v-model="tabsActive">
					<!-- 组件配置 -->
					<el-tab-pane name="1">
						<el-tooltip slot="label" effect="dark" content="组件配置" placement="top">
							<div><i class="el-icon-setting"></i></div>
						</el-tooltip>
						<el-form label-width="110px" label-position="left" size="mini">
							<template v-if="activeCompsIndex.length === 1">
								<el-form-item label="组件位置">
									<avue-input-number style="width: 90px" :precision="0" :disabled="activeObj.isLock" v-model="activeObj.left"></avue-input-number>
									<avue-input-number style="width: 90px; margin-left: 20px" :precision="0" :disabled="activeObj.isLock" v-model="activeObj.top"></avue-input-number>
								</el-form-item>
								<el-form-item label="组件尺寸">
									<avue-input-number style="width: 90px" :precision="0" :disabled="activeObj.isLock" v-model="activeComponent.width"></avue-input-number>
									<avue-input-number style="width: 90px; margin-left: 20px" :precision="0" :disabled="activeObj.isLock" v-model="activeComponent.height"></avue-input-number>
								</el-form-item>
								<el-collapse accordion>
									<el-collapse-item title="全局样式">
										<el-form-item label="透视">
											<avue-input-number :disabled="activeObj.isLock" v-model="activeComponent.perspective" :max="1000"></avue-input-number>
										</el-form-item>
										<el-form-item label="缩放">
											<avue-input-number :disabled="activeObj.isLock" v-model="activeComponent.scale" :max="10"></avue-input-number>
										</el-form-item>
										<el-form-item label="透明度">
											<avue-input-number :disabled="activeObj.isLock" :step="0.1" v-model="activeComponent.opacity" :max="1" :min="0"></avue-input-number>
										</el-form-item>
										<el-form-item label="进入动画" class="inline">
											<avue-select filterable allow-create :disabled="activeObj.isLock" v-model="activeComponent.animated" :dic="dicOption.animated"></avue-select>
										</el-form-item>
									</el-collapse-item>
								</el-collapse>
								<el-collapse accordion>
									<el-collapse-item title="旋转角度">
										<el-form-item label="X旋转度">
											<avue-input-number v-model="activeComponent.rotateX" :disabled="activeObj.isLock" :min="-360" :max="360"></avue-input-number>
										</el-form-item>
										<el-form-item label="Y旋转度">
											<avue-input-number v-model="activeComponent.rotateY" :disabled="activeObj.isLock" :min="-360" :max="360"></avue-input-number>
										</el-form-item>
										<el-form-item label="Z旋转度">
											<avue-input-number v-model="activeComponent.rotateZ" :disabled="activeObj.isLock" :min="-360" :max="360"></avue-input-number>
										</el-form-item>
									</el-collapse-item>
								</el-collapse>
								<el-collapse accordion>
									<el-collapse-item title="事件配置">
										<el-form-item label="事件穿透">
											<avue-switch :disabled="activeObj.isLock" v-model="activeObj.pointerEvent"></avue-switch>
										</el-form-item>
										<el-form-item label="追加参数">
											<avue-switch :disabled="disabled" v-model="activeObj.appendParams"> </avue-switch>
										</el-form-item>
									</el-collapse-item>
								</el-collapse>
								<el-form-item label="显示">
									<avue-switch :disabled="activeObj.isLock" v-model="activeObj.display"></avue-switch>
								</el-form-item>
								<template v-if="vaildProp('colorList')">
									<el-form-item label="系统配色">
										<avue-switch :disabled="activeObj.isLock" v-model="activeObj.switchTheme"></avue-switch>
									</el-form-item>
									<el-form-item label="配色选择" v-if="activeObj.switchTheme">
										<avue-select :disabled="activeObj.isLock" v-model="activeObj.theme" :dic="dicOption.themeList"> </avue-select>
									</el-form-item>
								</template>
								<component :is="activeComponent.prop + 'Option'"></component>
								<main-option></main-option>
							</template>
							<!-- 多选配置选项 -->
							<template v-if="activeCompsIndex.length > 1">
								<el-form-item label="水平方式" class="group-operate">
									<el-button-group>
										<el-tooltip content="左对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-fold" size="mini" @click="$refs.container.handlePostionSelect('left')"></el-button>
										</el-tooltip>
										<el-tooltip content="居中对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-operation" size="mini" @click="$refs.container.handlePostionSelect('center')"></el-button>
										</el-tooltip>
										<el-tooltip content="右对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-unfold" size="mini" @click="$refs.container.handlePostionSelect('right')"></el-button>
										</el-tooltip>
									</el-button-group>
								</el-form-item>
								<el-form-item label="垂直方式">
									<el-button-group>
										<el-tooltip content="顶对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-fold" size="mini" @click="$refs.container.handlePostionSelect('top')"></el-button>
										</el-tooltip>
										<el-tooltip content="中部对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-operation" size="mini" @click="$refs.container.handlePostionSelect('middle')"></el-button>
										</el-tooltip>
										<el-tooltip content="右对齐" placement="top">
											<el-button type="primary" icon="el-icon-s-unfold" size="mini" @click="$refs.container.handlePostionSelect('bottom')"></el-button>
										</el-tooltip>
									</el-button-group>
								</el-form-item>
								<el-form-item label-width="0">
									<el-button type="success" size="mini" class="block" @click="handleCompose">成组</el-button>
								</el-form-item>
								<el-form-item label-width="0">
									<el-button type="danger" size="mini" class="block" @click="handleCompDelete">删除</el-button>
								</el-form-item>
							</template>
							<!-- 主屏的配置项 -->
							<template v-if="activeCompsIndex.length === 0">
								<el-form-item label="大屏名称">
									<avue-input v-model="config.name"></avue-input>
								</el-form-item>
								<el-form-item label="大屏大小">
									<div class="flex">
										<avue-input-number style="width: 120px" v-model="config.width"></avue-input-number>
										<div style="margin: 0 3px">x</div>
										<avue-input-number style="width: 120px" v-model="config.height"></avue-input-number>
									</div>
								</el-form-item>
								<el-form-item label="放缩方式">
									<el-select v-model="config.zoomModel" placeholder="请选择放缩方式">
										<el-option label="全屏铺满" value="1"></el-option>
										<el-option label="宽度铺满" value="2"></el-option>
										<el-option label="高度铺满" value="3"></el-option>
										<el-option label="不缩放" value="4"> </el-option>
									</el-select>
								</el-form-item>
								<el-form-item label="大屏简介">
									<avue-input v-model="config.info" type="textarea" :min-rows="5"></avue-input>
								</el-form-item>
								<el-form-item label="背景颜色">
									<avue-input-color v-model="config.backgroundColor"></avue-input-color>
								</el-form-item>
								<el-form-item label="背景图片">
									<img :src="config.backgroundImage" @click="handleOpenImg('config.backgroundImage', 'background')" alt="" width="100%" />
									<el-input clearable v-model="config.backgroundImage">
										<div @click="handleOpenImg('config.backgroundImage', 'background')" slot="append">
											<i class="iconfont icon-img"></i>
										</div>
									</el-input>
								</el-form-item>
								<el-form-item label="全局请求头">
									<el-button size="mini" type="primary" @click="openGlobalApiConfig">配置</el-button>
								</el-form-item>
								<el-form-item label="全局变量配置">
									<el-button size="mini" type="primary" @click="openGlobalVariableConfig">配置</el-button>
								</el-form-item>
								<el-form-item label="滤镜配置">
									<div @click="changeFilterShow(config.filter.show)">
										<avue-switch v-model="config.filter.show"></avue-switch>
									</div>
								</el-form-item>
								<el-form-item label="对比度" v-if="config.filter.show">
									<avue-input-number :min="0" :max="200" v-model="config.filter.contrast"></avue-input-number>
								</el-form-item>
								<el-form-item label="亮度" v-if="config.filter.show">
									<avue-input-number :min="0" :max="200" v-model="config.filter.brightness"></avue-input-number>
								</el-form-item>
								<el-form-item label="不透明度" v-if="config.filter.show">
									<avue-input-number :min="0" :max="100" v-model="config.filter.opacity"></avue-input-number>
								</el-form-item>
								<el-form-item label="饱和度" v-if="config.filter.show">
									<avue-input-number :min="0" :max="200" v-model="config.filter.saturate"></avue-input-number>
								</el-form-item>
								<el-form-item label="色相" v-if="config.filter.show">
									<avue-input-number :min="0" :max="360" v-model="config.filter['hue-rotate']"></avue-input-number>
								</el-form-item>
								<el-form-item label="大屏水印">
									<avue-switch v-model="config.mark.show"></avue-switch>
								</el-form-item>
								<template v-if="config.mark.show">
									<el-form-item label="内容">
										<avue-input v-model="config.mark.text"></avue-input>
									</el-form-item>
									<el-form-item label="大小">
										<avue-input-number v-model="config.mark.fontSize"></avue-input-number>
									</el-form-item>
									<el-form-item label="颜色">
										<avue-input-color v-model="config.mark.color"></avue-input-color>
									</el-form-item>
									<el-form-item label="角度">
										<avue-input-number v-model="config.mark.degree"></avue-input-number>
									</el-form-item>
								</template>
							</template>
						</el-form>
					</el-tab-pane>
					<!-- 数据配置 -->
					<el-tab-pane name="2" v-if="vaildProp('dataList')">
						<el-tooltip slot="label" effect="dark" content="数据配置" placement="top">
							<div><i class="el-icon-document-copy"></i></div>
						</el-tooltip>
						<el-form label-width="110px" label-position="left" size="mini" class="dataForm">
							<div class="api-editor-title">字段映射</div>
							<avue-crud class="mapCrud" ref="crud" :option="dataMapFieldConfig" :data="dataMapConfig" @row-save="rowSave" @row-del="rowDel" @row-update="rowUpdate">
							</avue-crud>
							<el-form-item label="自动更新请求" class="auto-request">
								<avue-switch :disabled="activeObj.isLock" type="textarea" v-model="activeObj.autoRequest"></avue-switch>
								<div class="time">
									<avue-input-number :disabled="!activeObj.autoRequest" size="mini" v-model="activeObj.time"></avue-input-number>
									<span class="unit">秒一次</span>
								</div>
							</el-form-item>
							<div class="api-editor-title">数据响应</div>

							<el-form-item label-width="0" class="data-config-btn">
								<div class="data-timeline">
									<el-row class="row">
										<el-col span="6" class="name">数据类型</el-col>
										<el-col span="12" :offset="6">
											<!-- 查看订阅 -->
											<avue-select
												v-if="activeObj.isReceiveDataComp"
												:disabled="activeObj.isLock"
												v-model="activeObj.dataType"
												:dic="dicOption.dataType.filter(type => type.value !== 5)"
												@change="handleRes()"
											>
											</avue-select>
											<!-- 订阅数据 -->
											<avue-select
												v-else
												:disabled="activeObj.isLock"
												v-model="activeObj.dataType"
												:dic="dicOption.dataType.filter(type => type.value !== 4)"
												@change="handleRes()"
											>
											</avue-select>
										</el-col>
									</el-row>
									<el-row class="row">
										<el-col span="18" class="name">源数据</el-col>
										<el-col span="6">
											<el-button size="mini" type="primary" :disabled="activeObj.isLock" @click="handleDataProcess">
												<span>配置数据源</span>
											</el-button>
										</el-col>
									</el-row>
									<el-row class="row">
										<el-col span="18">数据过滤器<avue-switch :disabled="activeObj.isLock" type="textarea" v-model="activeObj.dataFilter"></avue-switch></el-col>
										<el-col span="6">
											<el-button size="mini" type="primary" :disabled="activeObj.isLock" @click="openCode('dataFormatter')">
												<span>配置过滤器</span>
											</el-button></el-col
										>
									</el-row>
									<el-row class="row">
										<el-col span="18">数据响应结果（只读）</el-col>
										<el-col span="6"><i title="刷新数据" class="el-icon-refresh" @click="readAOnlyData"></i></el-col>
									</el-row>
								</div>
							</el-form-item>

							<div class="data-response">
								<monaco-editor
									v-if="tabsActive == '2'"
									v-loading="readOnlyEdtor.loading"
									element-loading-text="数据响应结果拼命加载中"
									element-loading-spinner="el-icon-loading"
									element-loading-background="rgba(0, 0, 0, 0.8)"
									v-model="dataRes"
									ref="readonlyEditor"
									disabled
									height="250"
								></monaco-editor>
							</div>
						</el-form>
					</el-tab-pane>
					<!-- 交互事件配置 -->
					<el-tab-pane name="4" v-if="!vaildProp('', [undefined])">
						<el-tooltip slot="label" effect="dark" content="事件配置" placement="top">
							<div><i class="iconfont icon-peizhi"></i></div>
						</el-tooltip>

						<el-form label-width="110px" label-position="left" size="mini">
							<event-page :activeObj="activeObj" :childList="childList" :dataSource="dataRes"></event-page>
						</el-form>
					</el-tab-pane>
				</el-tabs>
			</div>
		</div>

		<!-- 数据处理弹窗 -->
		<codeedit
			@submit="codeClose"
			v-if="code.box && code.type != 'dataFormatter'"
			:type="code.type"
			:title="code.title"
			v-model="code.obj"
			:visible.sync="code.box"
			:compTitle="activeObj.title"
		></codeedit>

		<!-- 数据过滤弹窗 -->
		<el-drawer
			v-if="code.box && code.type == 'dataFormatter'"
			title="配置过滤器"
			:visible.sync="code.box"
			direction="rtl"
			size="350px"
			custom-class="filterDrawer"
			:append-to-body="true"
			:modal-append-to-body="false"
			:before-close="handleClose"
		>
			<filteredit @submit="codeClose" :type="code.type" :title="code.title" v-model="code.obj" :visible.sync="code.box" :compTitle="activeObj.title"> </filteredit>
		</el-drawer>

		<!-- 全局请求头配置 -->
		<el-dialog
			title="全局请求头配置"
			custom-class="data-config-dialog"
			:close-on-click-modal="true"
			:fullscreen="false"
			width="80%"
			:visible.sync="globalApi.visible"
			append-to-body
		>
			<el-form size="small" label-width="130px">
				<el-form-item label="请求头">
					<monaco-editor v-model="globalApi.headers" height="400" language="json"></monaco-editor>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button size="small" type="primary" icon="el-icon-refresh" @click="saveGlobalApi">保存</el-button>
			</span>
		</el-dialog>

		<!-- 全局变量配置 -->
		<el-dialog
			title="全局变量配置"
			custom-class="data-config-dialog"
			:close-on-click-modal="true"
			:fullscreen="false"
			width="80%"
			:visible.sync="globalVariable.visible"
			append-to-body
		>
			<el-form size="small" label-width="130px">
				<el-form-item label="变量">
					<monaco-editor v-model="globalVariable.variables" height="400" language="json"></monaco-editor>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button size="small" type="primary" icon="el-icon-refresh" @click="saveGlobalParams">保存</el-button>
			</span>
		</el-dialog>
		<!-- 配置数据源 -->
		<el-dialog title="配置数据源" custom-class="data-config-dialog" :close-on-click-modal="true" :fullscreen="false" width="80%" :visible.sync="show" append-to-body>
			<el-form size="small" v-if="show" label-width="130px">
				<!-- <el-form-item label="数据类型">
                    <avue-select
                        :disabled="activeObj.isLock"
                        v-model="activeObj.dataType"
                        :dic="dicOption.dataType"
                        @change="handleRes()"
                    >
                    </avue-select>
                </el-form-item> -->

				<!-- 静态数据 -->
				<template v-if="isStatic">
					<el-form-item label="数据值" label-position="top" class="data-config-item-value">
						<el-button size="mini" type="primary" icon="el-icon-edit" @click="openCode('data')">编辑数据值</el-button>
						<el-upload :show-file-list="false" :auto-upload="false" accept=".xls,.xlsx" :on-change="handleImport">
							<el-button size="small" icon="el-icon-upload" type="success">导入数据(Excel)</el-button>
						</el-upload>
					</el-form-item>
					<!-- <el-form-item label="转换器" label-position="top">
                        <el-button
                            size="small"
                            type="danger"
                            icon="el-icon-setting"
                            @click="openCode('dataFormatter')"
                            >数据转换器</el-button
                        >
                    </el-form-item> -->
				</template>
				<!-- sql -->
				<template v-else-if="isSql">
					<el-form-item label="数据源选择">
						<avue-select :dic="DIC.sql" v-model="db"></avue-select>
					</el-form-item>
					<el-form-item label="SQL语句" label-position="top">
						<monaco-editor v-model="sql" language="sql" height="200"></monaco-editor>
					</el-form-item>
					<!-- <el-form-item label="转换器" label-position="top">
                        <el-button
                            size="small"
                            type="danger"
                            icon="el-icon-setting"
                            @click="openCode('dataFormatter')"
                            >数据转换器</el-button
                        >
                    </el-form-item> -->
				</template>
				<!-- api -->
				<template v-else-if="isApi">
					<el-form-item label="接口地址">
						<avue-input v-model="activeObj.url"></avue-input>
					</el-form-item>
					<el-form-item label="请求方式">
						<avue-select v-model="activeObj.dataMethod" :dic="dicOption.dataMethod"></avue-select>
					</el-form-item>
					<el-form-item label="请求头" class="inline-row">
						<monaco-editor v-model="activeObj.dataHeader" height="100"></monaco-editor>
						<el-button size="small" type="primary" icon="el-icon-setting" @click="openCode('header')">编辑请求头</el-button>
					</el-form-item>
					<el-form-item label="请求参数" class="inline-row">
						<monaco-editor v-model="activeObj.dataQuery" height="100"></monaco-editor>
						<el-button size="small" type="primary" icon="el-icon-setting" @click="openCode('query')">编辑请求参数</el-button>
					</el-form-item>

					<!-- <el-form-item label="转换器" label-position="top">
                        <el-button
                            size="small"
                            type="danger"
                            icon="el-icon-setting"
                            @click="openCode('dataFormatter')"
                            >数据转换器</el-button
                        >
                    </el-form-item> -->
				</template>
				<!-- websocket -->
				<template v-else-if="isWs">
					<el-form-item label="WS地址">
						<avue-input v-model="activeObj.wsUrl"></avue-input>
					</el-form-item>
					<el-form-item label="请求参数">
						<el-button size="small" type="primary" icon="el-icon-setting" @click="openCode('dataQuery')">编辑函数</el-button>
					</el-form-item>
				</template>

				<template v-if="isReceiveDataComp">
					<el-form-item label="订阅编号" label-position="top" class="data-config-item-value">
						<avue-select
							v-model="activeObj.subscribeId"
							:dic="
								rceiveDataComps.map(comp => {
									return {
										label: comp.name,
										value: comp.index
									};
								})
							"
						></avue-select>
					</el-form-item>
					<el-form-item label="订阅层级" label-position="top" class="data-config-item-value">
						<avue-input v-model="activeObj.subscribeLevel"></avue-input>
					</el-form-item>
				</template>

				<el-form-item label="响应数据" v-if="!isReceiveDataComp">
					<el-button size="small" type="success" icon="el-icon-refresh" @click="handleRes">请求数据源</el-button>
					<monaco-editor
						v-loading="readOnlyEdtor.loading"
						element-loading-text="响应数据拼命加载中,请稍后..."
						element-loading-spinner="el-icon-loading"
						element-loading-background="rgba(0, 0, 0, 0.8)"
						v-model="dataRes"
						disabled
						height="350"
					></monaco-editor>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button size="small" @click="show = false">取 消</el-button>
				<el-button type="primary" @click="handleDataSourceSubmit" size="small">确 定</el-button>
				<!-- <el-button
                    v-if="activeObj.dataType == 2"
                    size="small"
                    type="danger"
                    @click="openCode('dataFormatter')"
                    >数据转换器</el-button
                > -->
			</span>
		</el-dialog>

		<!-- 查看数据弹框 -->
		<el-dialog append-to-body :close-on-click-modal="true" :visible.sync="lookDataShow" width="60%">
			<el-form size="small" v-if="lookDataShow" label-width="130px">
				<el-form-item label="响应数据">
					<monaco-editor
						v-loading="readOnlyEdtor.loading"
						element-loading-text="数据响应结果拼命加载中"
						element-loading-spinner="el-icon-loading"
						element-loading-background="rgba(0, 0, 0, 0.8)"
						v-model="dataRes"
						disabled
						height="600"
					></monaco-editor>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button size="small" type="primary" @click="handleRes">刷新数据</el-button>
			</span>
		</el-dialog>
	</div>
</template>
<script>
import MonacoEditor from '@/page/components/editor';
import layer from './group/layer';
import top from './group/top';
import headers from './group/header';
import imglist from './group/imglist';
import contentmenu from './group/contentmenu';
import codeedit from './group/code';
import filteredit from './group/filter';
import { dicOption, dataMapFieldConfig } from '@/option/config';
import init from '@/mixins/';
import components from '@/option/components';
import SketchRule from 'vue-sketch-ruler';
import { getList } from '@/api/db';
import crypto from '@/utils/crypto';
import EventPage from './components/eventPage.vue';
import { mapState, mapGetters } from 'vuex';
import { createFile, getFunction } from '@/utils/utils';
import { website } from '@/config.js';
export default {
	mixins: [init, components],
	components: {
		MonacoEditor,
		imglist,
		layer,
		codeedit,
		filteredit,
		top,
		headers,
		contentmenu,
		SketchRule,
		EventPage
	},
	data() {
		return {
			baseList: website.baseList,
			globalApi: {
				visible: false,
				url: '',
				headers: {
					Authorization: '',
					'Blade-Auth': ''
				},
				params: ''
			},
			globalVariable: {
				visible: false,
				variables: {}
			},
			layer: {
				thumbnailVersion: true,
				textVersion: false
			},
			dataMapConfig: [],
			dataMapFieldConfig: dataMapFieldConfig,
			menuId: 'avue-data-menu',
			menuShow: true,
			compShow: true,
			paramsShow: true,
			lookDataShow: false,
			show: false,
			keys: {
				ctrl: false
			},
			dataRes: '',
			db: '',
			sql: '',
			nav: [],
			DIC: {
				sql: []
			},
			loading: '',
			childProps: {
				label: 'name',
				value: 'index'
			},
			key: '',
			menuFlag: true,
			code: {
				box: false,
				type: '',
				obj: '',
				title: ''
			},
			form: {},
			dicOption: dicOption,
			tabsActive: '1',
			// 标尺
			scale: 1, //初始化标尺的缩放
			startX: -29, //x轴标尺开始的坐标数值
			startY: -29,
			lines: {
				//初始化水平标尺上的参考线
				h: [],
				v: []
			},
			rendIndex: 0, //重新渲染组件
			shadow: { x: 0, y: 0 }, // 阴影大小
			thick: 20, //标尺的厚度
			width: 0, // 标尺宽,后面会初始化
			height: 0, // 标尺高,后面会初始化
			isShowReferLine: true, // 显示参考线
			isImgOpen: true, //眼镜打开
			imgOpenData:
				'', // 左上角图片
			imgClose:
				'',
			dragSlide: false, // 拖动滚动条标记
			readOnlyEdtor: {
				loading: true
			}
		};
	},
	computed: {
		...mapState({
			compsList: state => state.compsList,
			globalEventList: state => state.event.globalEventList,
			activeComps: state => state.activeComps,
			areaData: state => state.areaData
		}),
		...mapGetters(['activeCompsIndex', 'rceiveDataComps']),
		isKeysCtrl() {
			return this.keys.ctrl == true;
		},
		isStatic() {
			return this.activeObj.dataType == 0;
		},
		isApi() {
			return this.activeObj.dataType == 1;
		},
		isSql() {
			return this.activeObj.dataType == 2;
		},
		isWs() {
			return this.activeObj.dataType == 3;
		},
		isReceiveDataComp() {
			return this.activeObj.dataType == 5;
		},
		isFolder() {
			return this.activeObj.children;
		},
		isActive() {
			return this.active.length !== 0;
		},
		isSelectActive() {
			return this.active.length > 1;
		},
		childList() {
			return this.list
				.filter(ele => {
					if (ele.children) return false;
					let component = ele.component || {};
					return component.prop;
				})
				.filter(v => v.index != this.activeObj.index); // 过滤掉自身
		},
		activeComponent() {
			return this.activeObj.component || {};
		},
		activeOption() {
			return this.activeObj.option || {};
		},
		activeObj() {
			let item = this.findlist(this.activeCompsIndex) || {};
			if (!item.child) item.child = {};
			return item;
		},
		activeList() {
			let result = [];
			this.active.forEach(ele => {
				let item = this.findnav(ele);
				result.push(item.item);
			});
			return result;
		},
		/* 标尺用的 */
		palette() {
			return {
				bgColor: '#181b24', // ruler bg color
				longfgColor: '#BABBBC', // ruler longer mark color
				shortfgColor: '#9C9C9C', // ruler shorter mark color
				fontColor: '#fff', // ruler font color
				shadowColor: '#181b24', // ruler shadow color
				lineColor: '#EB5648',
				borderColor: '#B5B5B5',
				cornerActiveColor: '#fff'
			};
		},
		// 画布大小,一定要是computer里面,否则缩放页面会失效
		canvasStyle() {
			// return {
			//     width: this.config.width - 350 + "px"
			// };
			return {
				width: window.innerWidth - (this.menuShow ? 180 : 0) - (this.paramsShow ? 350 : 0) + 'px'
				// transform: `scale(${this.scale})`
			};
		},
		sketchRuleScale() {
			return this.config.scale / 100;
		}
	},
	inject: ['reload', 'contain'],
	watch: {
		tabsActive: {
			handler(val) {
				console.log('tabsActive');
			}
		},
		activeObj: {
			handler(val) {
				if (this.activeObj.sql && this.isSql) {
					let mode = JSON.parse(crypto.decrypt(this.activeObj.sql));
					this.db = mode.id;
					this.sql = mode.sql;
				} else {
					this.db = '';
					this.sql = '';
				}
				if (val.data) {
					this.handleRes();
				}
			},
			deep: true
		},
		menuFlag() {
			this.setResize();
		},
		overactive(n, o) {
			[o, n].forEach((ele, index) => {
				if (!ele) return;
				this.setActive(ele, index === 1, 'setOverActive');
			});
		},
		active(n, o) {
			[(o, n)].forEach((ele, index) => {
				ele.forEach(item => {
					this.setActive(item, index === 1, 'setActive');
				});
			});
			// 初始化选项卡 1
			this.tabsActive = '1';
			this.listen();
		},
		activeComps: {
			handler(value) {
				// 初始化选项卡 1
				this.tabsActive = '1';
			}
		},
		'config.scale': {
			handler(value) {
				this.scale = parseFloat((value / 100).toFixed(2));
			},
			deep: true
		}
	},
	created() {
		this.listen();
		this.iniresize();
		this.initSqlList();
		this.$notify({
			title: '提示',
			type: 'warning',
			message: '操作编辑页前请确认没有其他同事操作，避免自己的修改被覆盖',
			duration: 5000
		});
	},
	mounted() {
		this.initFun();
		this.$nextTick(() => {
			this.initSize();
		});
	},
	beforeDestroy() {
		document.onkeydown = null;
	},
	methods: {
		handleImport(file, fileLis) {
			this.$Export.xlsx(file.raw).then(data => {
				this.activeObj.data = data.results;
				this.$message.success('导入成功');
				this.handleRes();
			});
		},
		handleRefresh() {
			return this.$refs.container.handleRefresh();
		},
		handleDataSourceSubmit() {
			this.handleRes();
			this.show = false;
		},
		async handleRes() {
			const that = this;
			that.readOnlyEdtor.loading = true;
			if (that.isSql) {
				that.$set(
					that.activeObj,
					'sql',
					crypto.encrypt(
						JSON.stringify({
							id: that.db,
							sql: that.sql
						})
					)
				);
				// if (that.sql == "") {
				//     that.readOnlyEdtor.loading = false;
				// }
			}
			try {
				let res = await that.handleRefresh();
				if (!that.validatenull(res)) {
					let data = JSON.stringify(res || {}, null, 4);
					// 处理字段映射
					this.dataMapConfig = this.formatterFiledMap(res);
					// console.log("this.dataMapConfig", this.dataMapConfig);
					let result = this.handleDataMapFinished(data);
					that.dataRes = result;
				} else {
					that.dataRes = '';
				}
				setTimeout(() => {
					that.readOnlyEdtor.loading = false;
					// that.show = false;
				}, 200);
			} catch (error) {
				console.log('error', error);
			}
		},
		readAOnlyData() {
			this.readOnlyEdtor.loading = true;
			this.dataRes = this.handleDataMapFinished(this.dataRes);
			setTimeout(() => {
				this.readOnlyEdtor.loading = false;
			}, 200);
		},
		// 处理字段映射
		formatterFiledMap(value) {
			let resultField = [];
			if (Array.isArray(value)) {
				Object.keys(value[0]).map(key => {
					let filedIndex = this.activeObj.dataMapConfig.findIndex(config => config.field == key);
					resultField.push({
						field: key,
						mapField: filedIndex > -1 ? this.activeObj.dataMapConfig[filedIndex].mapField : ''
					});
				});
			} else {
				Object.keys(value).map(key => {
					let filedIndex = this.activeObj.dataMapConfig.findIndex(config => config.field == key);
					resultField.push({
						field: key,
						mapField: filedIndex > -1 ? this.activeObj.dataMapConfig[filedIndex].mapField : ''
					});
				});
			}
			return resultField;
		},
		handleDataProcess() {
			this.show = true;
			this.dataRes = '';
			this.$nextTick(() => {
				let result = false;
				if (this.isSql && !this.validatenull(this.sql)) {
					result = true;
				} else if (this.isApi && !this.validatenull(this.activeObj.url)) {
					result = true;
				} else {
					result = true;
				}
				if (result) this.handleRes();
			});
		},
		lookData() {
			this.lookDataShow = true;
			this.dataRes = '';
			this.$nextTick(() => {
				let result = false;
				if (this.isSql && !this.validatenull(this.sql)) {
					result = true;
				} else if (this.isApi && !this.validatenull(this.activeObj.url)) {
					result = true;
				} else {
					result = true;
				}
				if (result) this.handleRes();
			});
		},
		initSqlList() {
			getList(1, 100).then(res => {
				const data = res.data.data;
				this.DIC.sql = data.records.map(ele => {
					return {
						label: ele.name,
						value: ele.id
					};
				});
			});
		},
		codeClose(value) {
			if (this.configData.includes(this.code.type)) {
				// this.config[this.code.type] = value;
				if (this.code.type == 'header') {
					this.activeObj.dataHeader = value;
				}
				if (this.code.type == 'query') {
					this.activeObj.dataQuery = value;
				}
			} else {
				this.$set(this.activeObj, this.code.type, value);
				// this.activeObj[this.code.type] = value;
			}
			this.handleRes();
		},
		openCode(type) {
			this.code.type = type;
			// 请求参数，请求头
			if (this.configData.includes(type)) {
				if (type == 'header') {
					this.code.obj = this.activeObj.dataHeader;
					this.code.title = '请求头';
				}
				if (type == 'query') {
					this.code.obj = this.activeObj.dataQuery;
					this.code.title = '请求参数';
				}

				this.code.box = true;
			} else {
				this.code.title = '数据转换器';
				this.code.obj = this.activeObj[type];
				this.code.box = true;
			}
		},
		openGlobalApiConfig() {
			this.globalApi.visible = true;
			this.globalApi.headers = this.config.header || this.globalApi.headers;
		},
		saveGlobalApi() {
			let header = this.globalApi.headers;
			this.config.header = typeof header == 'string' ? JSON.parse(header) : header;
			this.globalApi.visible = false;
		},
		openGlobalVariableConfig() {
			this.globalVariable.visible = true;
			this.globalVariable.variables = this.config.variables || this.globalVariable.variables;
		},
		saveGlobalParams() {
			let variables = this.globalVariable.variables;
			this.config.variables = typeof variables == 'string' ? JSON.parse(variables) : variables;
			this.globalVariable.visible = false;
			this.$store.dispatch('SetGlobalVariableAsync', variables);
		},
		initFun() {
			['setScale', 'setResize'].forEach(ele => {
				this[ele] = this.$refs.container[ele];
			});
			// ["handleAdd"].forEach((ele) => {
			//     this[ele] = this.$refs.top[ele];
			// });
		},
		// 右键菜单
		handleContextMenu(item = {}, done) {
			if (!item.index || this.isKeysCtrl) return;
			else if (!this.isSelectActive) {
				// this.active = [item.index];
				// this.activeIndex = item.index;
			}
			done();
		},
		//  67:C 86:V 83:S
		//监听键盘的按键
		listen() {
			const that = this;
			document.onkeydown = e => {
				that.keys.ctrl = e.keyCode === 17;
				// 快捷键操作
				// 按下ctrl+delete
				if (e.ctrlKey && e.keyCode == 46) {
					// e.preventDefault();
					if (that.activeCompsIndex && that.activeCompsIndex.length > 0) {
						that.handleCompDelete();
					}
				}

				// 撤销 ctrl+z
				if (e.ctrlKey && e.keyCode == 90 && that.canUndo) {
					that.editorUndo();
				}

				// 重做 ctrl+y
				if (e.ctrlKey && e.keyCode == 89 && that.canRedo) {
					that.editorRedo();
				}
				// 复制 ctrl+0
				if (e.ctrlKey && e.keyCode == 96) {
					that.$refs.contentmenu.handleCopy();
				}
				// 粘贴 ctrl+.
				if (e.ctrlKey && e.ctrlKey && e.keyCode == 110) {
					that.$refs.contentmenu.handlePaste();
				}

				// 保存 ctrl+s
				if (e.ctrlKey && e.keyCode == 83) {
					e.preventDefault();
					that.$refs.header.handleBuild();
				}
				if (e.target.nodeName == 'TEXTAREA' || e.target.nodeName == 'INPUT') return;
				// 按下空格键
				if (e.ctrlKey && e.keyCode == 32) {
					e.preventDefault();
					that.keys.space = true;
				}
			};
			document.onkeyup = () => {
				that.keys.ctrl = false;
			};
		},
		setActive(val, result, fun) {
			const obj = this.$refs.container.getDragObj(val);
			if (!this.validatenull(obj)) obj[0][fun](result);
		},
		// 成组
		handleCompose() {
			let {
				style: { height, left, top, width },
				components
			} = this.areaData;
			let folder = createFile();
			folder.left = left;
			folder.top = top;
			folder.component.width = width;
			folder.component.height = height;
			this.activeComps.forEach(comp => {
				comp.oldLeft = comp.left;
				comp.oldTop = comp.top;
				if (comp.left > left) {
					comp.left = comp.left - left;
				} else if (comp.left == left) {
					comp.left = 0;
				}

				if (comp.top > top) {
					comp.top = comp.top - top;
				} else if (comp.top == top) {
					comp.top = 0;
				}
			});
			folder.children = this.activeComps;
			let areaCompIds = components.map(comp => comp.index);

			this.$store.commit('clearActiveComps');
			this.$store.commit('clearCanvasCompList', areaCompIds);
			this.$store.commit('setCanvasCompsList', [folder]);
		},
		//批量删除
		handleCompDelete() {
			this.$confirm(`是否批量删除${this.activeComps.map(comp => comp.name).join(',')} 共${this.activeComps.length}个组件?`, '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				this.activeComps.forEach(comp => {
					let { itemList, itemIndex } = this.findnav(comp.index);
					itemList.splice(itemIndex, 1);
				});
				this.$store.commit('clearActiveComps');
				this.$refs.container.handleHideArea(); // 清除框选
			});
		},
		vaildProp(name, list) {
			if (list) return list.includes(this.activeComponent.prop) || this.active.length > 1;
			return this.dicOption[name].includes(this.activeComponent.prop);
		},
		formatTooltip(val) {
			return parseInt(val);
		},
		//打开图库
		handleOpenImg(item, type) {
			this.$refs.imglist.openImg(item, type);
		},
		//图库框回调赋值
		handleSetimg(val, type) {
			let params = type.split('.')[1];
			if (type.includes('config')) {
				this.config[params] = val;
			} else if (type.includes('activeObj.data.value')) {
				this.activeObj.data.value = val;
			} else if (type.includes('activeObj.data')) {
				this.activeObj.data = val;
			} else if (type.includes('activeObj')) {
				this.activeObj[params] = val;
			} else if (type.includes('activeOption')) {
				this.activeOption[params] = val;
			}
		},
		/* **************************标尺方法开始******************************* */
		// 滚轮触发
		handleScroll(d) {
			const screensRect = this.$refs.screensRef.getBoundingClientRect();
			const canvasRect = this.$refs.canvas.getBoundingClientRect();
			// 标尺开始的刻度
			const startX = parseFloat(((-d - this.thick) / this.scale).toFixed(2));
			const startY = parseFloat(((-d - this.thick) / this.scale).toFixed(2));
			this.startX = startX >> 0;
			this.startY = startY >> 0;
		},
		// 控制缩放值
		handleWheel(e) {
			// if (e.ctrlKey || e.metaKey) {
			//     e.preventDefault();
			//     const nextScale = parseFloat(
			//         Math.max(0.2, this.scale - e.deltaY / 500).toFixed(2)
			//     );
			//     // this.scale = nextScale;
			// }
			// this.$nextTick(() => {
			//     this.handleScroll();
			// });
		},
		// 初始化标尺数值
		initSize() {
			const domW = this.$refs.section;
			let width = this.config.width;
			let height = this.config.height;
			if (domW && domW.style) {
				// domW.style.width = width + "px";
				// domW.style.height = calc(100vh - 40px);
			}
			this.width = width - this.thick;
			this.height = height - this.thick;
			// 画布阴影部分
			this.shadow = { x: 0, y: 0, width, height };
			// 滚动居中
			let dom = this.$refs.containerRef && this.$refs.containerRef.getBoundingClientRect();
			if (this.$refs.screensRef) {
				this.$refs.screensRef.scrollLeft = dom.width / 2 - this.thick;
				this.$refs.screensRef.scrollTop = dom.height / 2 - this.thick;
			}
		},
		// resize
		iniresize() {
			window.addEventListener('resize', () => {
				let width = this.width;
				let height = this.height;
				this.initSize();
				let rate = Math.min(this.width / width, this.height / height);
				this.scale = rate > 1 ? rate * 0.5 : rate;
				this.rendIndex++;
			});
		},
		changeCanvasScale(value, d) {
			this.scale = value;
			this.handleScroll(d);
		},
		// 图片点击事件
		imgClick() {
			this.isShowReferLine = !this.isShowReferLine;
		},
		// 鼠标按下事件
		dragMousedown(e) {
			// 如果按下了空格键,且按下鼠标左键,那么鼠标变抓手,开启滚动条随鼠标拖动的操作
			this.handleInitActive();
			if (this.keys.space) {
				this.dragSlide = true;
				window.stardragEvent = e;
				window.startSlideX = this.$refs.screensRef.scrollLeft;
				window.startSlideY = this.$refs.screensRef.scrollTop;
			}
		},
		//鼠标抬起操作
		dragMouseup() {
			this.dragSlide = false;
		},
		// 鼠标移动
		dragMousemove(e) {
			if (this.dragSlide) {
				let x = e.clientX - window.stardragEvent.clientX;
				let y = e.clientY - window.stardragEvent.clientY;
				this.$refs.screensRef.scrollLeft = window.startSlideX - x;
				this.$refs.screensRef.scrollTop = window.startSlideY - y;
			}
		},
		selectNav(item) {
			if (Array.isArray(item)) {
				this.active = this.active.concat(item);
			} else if (this.isKeysCtrl) {
				this.active.push(item);
			} else if (!this.active.includes(item)) {
				this.active = [item];
				this.activeIndex = item;
			}
		},
		handleDataMapFinished(value) {
			let mapObj = {};
			for (const item of this.activeObj.dataMapConfig) {
				mapObj[item.field] = item.mapField;
			}
			let data = JSON.parse(value || '{}');
			if (Array.isArray(data)) {
				data = data.map(d => {
					for (const [key, value] of Object.entries(mapObj)) {
						if (value) {
							console.log(value, 'value');
							d[value] = d[key];
						}
					}
					return d;
				});
			} else {
				for (const key in data) {
					if (mapObj[key]) {
						data[mapObj[key]] = data[key];
					}
				}
			}
			let result = JSON.stringify(data, null, 4);
			// this.$set(this.activeObj, "data", data);
			return result;
		},
		rowSave(row, done) {
			this.dataMapConfig.push(this.deepClone(row));
			this.activeObj.dataMapConfig = this.dataMapConfig;
			done();
		},
		rowDel(row, index) {
			this.dataMapConfig.splice(index, 1);
			this.activeObj.dataMapConfig = this.dataMapConfig;
		},
		rowUpdate(row, index, done) {
			this.dataMapConfig.splice(index, 1, this.deepClone(row));
			this.activeObj.dataMapConfig = this.dataMapConfig;
			done();
		},
		// 滤镜功能
		changeFilterShow(value) {
			this.$message({
				showClose: true,
				message: `${value ? '滤镜已开启应用' : '滤镜已关闭'}`,
				type: 'success'
			});
		},
		// 图层展示模式切换
		handleFlag() {
			this.layer['thumbnailVersion'] = !this.layer['thumbnailVersion'];
			this.layer['textVersion'] = !this.layer['textVersion'];
			this.$refs.layer && this.$refs.layer.handleClearEditStatus();
		},
		handleContentmenu({ type, compsIndex }) {
			this.$refs.container.setSubCompsActive(compsIndex);
		},
		handleReCompName() {
			this.$set(this.activeObj, 'isRename', true);
		},
		editCompName() {
			this.$set(this.activeObj, 'isRename', false);
		}
	}
};
</script>
<style lang="scss">
@import '../styles/style.scss';

.refer-line-img {
	position: absolute;
	left: 0;
	z-index: 5;
	width: 20px;
	height: 20px;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	img {
		width: 100%;
	}
}

#screens {
	// position: absolute;
	// top: 0;
	// left: 0;
	width: 100%;
	height: 100%;
	// overflow: auto;
}

.screen-container {
	width: 100%;
	height: 100%;
	position: absolute;
	overflow: hidden;
	background: url(https://img.alicdn.com/tfs/TB184VLcPfguuRjSspkXXXchpXa-14-14.png) repeat;
}

.dragghanle {
	cursor: pointer;
}

.canvas {
	position: absolute;
	left: 0px;
	top: 0px;
	height: 100%;
	// height: calc(100% - 50px);
	// min-width: 1200px;
}

.section {
	flex: 1;
	height: calc(100vh - 40px);
	min-width: 700px;
	overflow: hidden;
	position: relative;
}

// 操作 数据
.dataForm {
	.dataForm-dataRes {
		margin-bottom: 10px;

		.el-form-item__content {
			text-align: right;
			cursor: pointer;
		}
	}
}
.el-dialog__wrapper {
	// overflow: visible;
}
.data-config-dialog {
	// overflow: visible !important;
	margin-top: 5vh !important;
	.el-dialog__body {
		padding: 0;
		.el-form-item--small {
			margin-bottom: 10px !important;
		}
		.data-config-item-value {
			.el-form-item__content {
				display: flex;
				button {
					margin-right: 10px;
				}
			}
		}
	}
	.inline-row {
		width: 50%;
		display: inline-block;
	}
}
.data-config-btn {
	margin-left: 20px;
}
.filterDrawer {
	background-color: #1b1c1f;
	.el-drawer__header {
		margin-bottom: 0;
		padding: 10px;
		background-color: #242629;
	}
}
</style>
<style lang="scss" scoped>
.event-item-container {
	padding: 10px;
}

.el-form {
	.compId {
		font-size: 12px;
		letter-spacing: 0;
		text-align: center;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		text-indent: 0;
	}
	.auto-request {
		::v-deep .el-form-item__label {
			color: rgb(188, 201, 212) !important;
		}
		::v-deep .el-form-item__content {
			display: flex;
			align-items: center;
			.time {
				display: flex;
				align-items: center;
				margin-left: 10px;
				.unit {
					margin-left: 5px;
					white-space: nowrap;
				}
			}
		}
	}
	.data-config-btn {
		margin: 5px 5px 5px 20px;
		.data-timeline {
			.row {
				margin-bottom: 5px;

				.el-icon-refresh {
					cursor: pointer;
					color: #0b71e6;
				}
				&:last-child {
					margin-bottom: 0px;
				}
			}
		}
	}
}
.mapCrud {
	::v-deep .avue-crud__menu {
		display: none;
	}
}
.build {
	.pages-wrapper {
		height: calc(100% - 40px);
	}
}
.style-ruler {
	height: calc(100vh - 91px);
}

.api-editor-title {
	padding: 10px;
	font-size: 12px;
	border-top: 1px solid #282f3a;
	border-bottom: 1px solid #282f3a;
	color: #fff;
}

.menu.params {
	::v-deep .el-tabs__item {
		background-color: #13161a;
		&.is-active {
			background-color: #1d2126;
		}
	}
}
.data-response {
	margin: 0 10px;
	box-sizing: border-box;
	border: 1px solid #282f3a;
}
</style>
